﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace DAH_TD_
{
    public class Enemy
    {
        private ContentManager e_content;
        Texture2D enemyTexture;
        Texture2D hp_low;
        Texture2D hp_middle;
        Texture2D hp_high;
        TileMap map;
        Vector2 actualTile;
        Vector2 position = new Vector2(0, 200);
        public Vector2 getPosition() { return this.position; }
        Vector2 moveDirection;

        Rectangle boundarie;
        public Rectangle getBoundarie() { return this.boundarie; }

        float moveSpeed = 1;
        float moveDistance = 0;
        bool changeDirection = false;
        bool up_last = false;
        bool down_last = false;
        bool right_last = false;

        //bool spawn;

        float hpInPercent;
        float hp;
        public float getHp() { return this.hp; }
        public void setHp(float hp) { this.hp = hp; }
        float hpMax;

        float armor;
        int type;

        int spawntime = 2;
        public int getSpawntime() { return this.spawntime; }
        bool go = false;
        public bool ifGo() { return this.go; }
        public void Go() { this.go = true; }
        bool active = true;
        public bool Active() { return this.active; }

        // aktuellenTile ermitteln
        private void setActualTile(TileMap map)
        {
            // in x-Richtung: 
            int b = map.getTileWidth();
            float xTile = position.X / b;
            int xPos = (int)xTile;
            actualTile.X = xPos;
            // in y-Richtung: 
            int h = map.getTileHeight();
            float yTile = position.Y / h;
            int yPos = (int)yTile;
            actualTile.Y = yPos;
        }

        // Tile zum Spawnen ermitteln
        private void setSpawn(TileMap map)
        {
            int mapHoehe = map.GetHeight();
            int tileHoehe = map.getTileHeight();
            Tile tile = new Tile();
            Vector2 spawnPosition = new Vector2();

            // X-Koordinaten setzen
            spawnPosition.X = 0;

            // jedes Tile in letzter Kachelreihe auf "Weg" checken
            for (int i = 0; i < mapHoehe; i++)
            {
                tile = map.GetTile(0, i);
                if (tile.weg == true)
                {
                    // wenn gefunden: Y-Koordinaten setzen
                    spawnPosition.Y = i * tileHoehe; // Kachelposition * Kachelhoehe
                }
            }

            this.position = spawnPosition;
        }

        // Bewegung des Gegners
        private void move(TileMap map)
        {
            if (moveDistance <= 0) { changeDirection = true; }

            //  abcheken der anliegenden Kacheln für neue Richtung
            if (changeDirection)
            {
                // Mögliche Richtungen
                bool right = checkNextTileRight();
                bool down = checkNextTileLower();
                bool up = checkNextTileUpper();

                if (right) { GoRight(); moveDistance = map.getTileWidth(); }
                if (up && !right && !down_last) { GoUp(); moveDistance = map.getTileHeight(); }
                if (down && !right && !up_last) { GoDown(); moveDistance = map.getTileHeight(); }

                changeDirection = false;
            }

            // solange nicht anderes gesagt in bestimmte Richtung laufen
            if (!changeDirection)
            {
                position.X += moveDirection.X;
                position.Y += moveDirection.Y;
                moveDistance -= moveSpeed;
            }
        }

        // Kachelabfrage: Links von aktueller Position
        private bool checkNextTileRight()
        {
            int x = (int)this.actualTile.X + 1;
            if (x < 0) { x = 0; }
            if (x >= map.GetWidth()) { x = map.GetWidth() - 1; }
            int y = (int)this.actualTile.Y;
            if (y < 0) { y = 0; }
            if (y >= map.GetHeight()) { x = map.GetHeight() - 1; }
            if (map.GetTile(x, y).weg == true) { return true; }
            else { return false; }
        }

        // Kachelabfrage: Oben von aktueller Position
        private bool checkNextTileUpper()
        {
            int x = (int)this.actualTile.X;
            if (x < 0) { x = 0; }
            if (x >= map.GetWidth()) { x = map.GetWidth() - 1; }
            int y = (int)this.actualTile.Y - 1;
            if (y < 0) { y = 0; }
            if (y >= map.GetHeight()) { x = map.GetHeight() - 1; }
            if (map.GetTile(x, y).weg == true) { return true; }
            else { return false; }
        }

        // Kachelabfrage: Unten von aktueller Position
        private bool checkNextTileLower()
        {
            int x = (int)this.actualTile.X;
            if (x < 0) { x = 0; }
            if (x >= map.GetWidth()) { x = map.GetWidth() - 1; }
            int y = (int)this.actualTile.Y + 1;
            if (y < 0) { y = 0; }
            if (y >= map.GetHeight()) { x = map.GetHeight() - 1; }
            if (map.GetTile(x, y).weg == true) { return true; }
            else { return false; }
        }

        // Bewegungsrichtungen
        private void GoUp()
        {
            moveDirection.X = 0;
            moveDirection.Y = moveSpeed * -1;
            up_last = true; right_last = false; down_last = false;
        }

        private void GoDown()
        {
            moveDirection.X = 0;
            moveDirection.Y = moveSpeed;
            down_last = true; up_last = false; right_last = false;
        }

        private void GoRight()
        {
            moveDirection.X = moveSpeed;
            moveDirection.Y = 0;
            right_last = true; up_last = false; down_last = false;
        }

        public Enemy(TileMap map)
        {
            this.map = map;
        }

        public Enemy(TileMap map, int type)
        {
            this.map = map;
            // hier spawn noch festzulegen
            boundarie = new Rectangle((int)position.X, (int)position.Y, map.getTileWidth(), map.getTileHeight());

            switch (type)
            {
                case 0:
                    break;
                case 1:
                    {
                        this.type = 1;
                        this.hpMax = this.hp = 100;
                        this.armor = 0;
                        this.moveSpeed = 1f;
                        break;
                    }
                case 2:
                    {
                        this.type = 2;
                        this.hpMax = this.hp = 200;
                        this.armor = 1;
                        this.moveSpeed = 0.5f;
                        break;
                    }
            }

        }


        public bool Initialize(ContentManager content)
        {
            this.e_content = content;
            return true;
        }

        public void Update()
        {
            //if (go) 
            //{
            setActualTile(map);
            //setSpawn(map);
            move(map);
            boundarie.X = (int)position.X;
            boundarie.Y = (int)position.Y;
            //}
        }

        public void LoadContent()
        {
            switch (type)
            {
                case 1: enemyTexture = e_content.Load<Texture2D>("Graphics/Dunkel/Mole");
                    break;
                case 2: enemyTexture = e_content.Load<Texture2D>("Graphics/Dunkel/Mothership");
                    break;
            }

            hp_high = e_content.Load<Texture2D>("Graphics/hpHigh");
            hp_middle = e_content.Load<Texture2D>("Graphics/hpMiddle");
            hp_low = e_content.Load<Texture2D>("Graphics/hpLow");
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(enemyTexture, new Rectangle((int)position.X, (int)position.Y, map.getTileWidth(), map.getTileHeight()), Color.White);
            hpInPercent = hp / hpMax * 100;
            if (hpInPercent > 50) { spriteBatch.Draw(hp_high, new Rectangle((int)position.X, (int)position.Y, map.getTileWidth() * (int)hpInPercent / 100, map.getTileHeight()), Color.White); }
            if (hpInPercent <= 50 & hpInPercent > 20) { spriteBatch.Draw(hp_middle, new Rectangle((int)position.X, (int)position.Y, map.getTileWidth() * (int)hpInPercent / 100, map.getTileHeight()), Color.White); }
            if (hpInPercent <= 20 & hpInPercent > 0) { spriteBatch.Draw(hp_low, new Rectangle((int)position.X, (int)position.Y, map.getTileWidth() * (int)hpInPercent / 100, map.getTileHeight()), Color.White); }
        }
    }
}
